/*
    Copyright (C) 2021 Huawei Device Co., Ltd.
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
 */

package com.danikula.videocache.onefileStrategy;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * 分节点缓存 已下载区域集合工具类
 */
public class Solution {
    /**
     * 合并当前已下载的区域 如果两个区域有交集
     *
     * @param arr 当前已下载的区域集合
     * @return 合并后的已下载区域集合
     */
    public static long[][] merge(long[][] arr) {
        if (arr == null || arr.length <= 1) {
            return arr;
        }
        List<long[]> list = new ArrayList<>();
        /**
         *  按照两个组的左面的数进行比较
         *  [1,3]   [2,4]  比较1和2     小的排前面，大的排后面
         */
        Arrays.sort(arr, (left, right) -> (int) (left[0] - right[0]));
        int index = 0;
        int arrLength = arr.length;
        while (index < arrLength) {
            long left = arr[index][0];
            long right = arr[index][1];
            while (index < arrLength - 1 && right >= arr[index + 1][0]) {
                right = Math.max(right, arr[index + 1][1]);
                index++;
            }
            list.add(new long[]{left, right});
            index++;
        }
        return list.toArray(new long[list.size()][2]);
    }

    /**
     * 获取下载区域的起始点
     *
     * @param offset    请求起始点
     * @param videoSize 视频文件长度
     * @param arr       已下载区域缓存集合
     * @return 需要下载的起止点集合
     */
    public static long[] getDownloadArea(long offset, long videoSize, long[][] arr) {
        if (offset < 0) {
            return new long[]{0, videoSize <= 0 ? Long.MAX_VALUE : videoSize};
        }
        if (arr == null || arr.length <= 1) {
            return new long[]{0, videoSize <= 0 ? Long.MAX_VALUE : videoSize};
        }
        /*
         * Arrays.sort(arr,(a,b)->a[0]-b[0]);
         * 按照两个组的左面的数进行比较
         * [1,3]   [2,4]  比较1和2     小的排前面，大的排后面
         */
        Arrays.sort(arr, (left, right) -> (int) (left[0] - right[0]));
        int index = 0;
        int arrLength = arr.length;
        long tempEnd = 0;
        long tempRight = Long.MAX_VALUE;
        while (index < arrLength) {
            long left = arr[index][0];
            long right = arr[index][1];
            if (videoSize > 0 && right > videoSize) {
                right = videoSize;
            }
            int temp = index + 1;
            tempEnd = temp < arr.length ? arr[temp][0] : videoSize;
            if (offset < left) {
                return new long[]{offset, left};
            } else if (left <= offset && right > offset) {
                return new long[]{right, tempEnd};
            } else {
                if (arr[temp][0] - offset >= 0 && arr[temp][0] - offset < tempRight) {
                    tempRight = arr[temp][0];
                }
            }
            index++;
        }
        if (tempEnd == offset) {
            if (videoSize > 0) {
                tempEnd = videoSize;
            } else {
                tempEnd = Long.MAX_VALUE;
            }
        }
        if (tempRight == Long.MAX_VALUE) {
            tempRight = tempEnd;
        }
        return new long[]{offset, tempRight};
    }

}